50ea21c2a13e20eac0908f4262828b3ab8eff21f,src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java,StaticTypeCheckingVisitor,inferReturnTypeGenerics,#ClassNode#MethodNode#Expression#,1853

Before Change


            }
        }
        if (!returnType.isUsingGenerics()) return returnType;
        GenericsType[] returnTypeGenerics = returnType.getGenericsTypes();
        List<GenericsType> placeholders = new LinkedList<GenericsType>();
        for (GenericsType returnTypeGeneric : returnTypeGenerics) {
            if (returnTypeGeneric.isPlaceholder() || returnTypeGeneric.isWildcard()) {
                placeholders.add(returnTypeGeneric);
            }
        }
        if (placeholders.isEmpty()) return returnType; // nothing to infer
        Map<String,GenericsType> resolvedPlaceholders = new HashMap<String, GenericsType>();
        GenericsUtils.extractPlaceholders(receiver, resolvedPlaceholders);
        GenericsUtils.extractPlaceholders(method.getReturnType(), resolvedPlaceholders);
        // then resolve receivers from method arguments
        Parameter[] parameters = method.getParameters();
        boolean isVargs = isVargs(parameters);
        ArgumentListExpression argList = InvocationWriter.makeArgumentList(arguments);
        List<Expression> expressions = argList.getExpressions();
        int paramLength = parameters.length;
        for (int i = 0; i < paramLength; i++) {
            boolean lastArg = i== paramLength -1;
            ClassNode type = parameters[i].getType();
            if (!type.isUsingGenerics() && type.isArray()) type=type.getComponentType();
            if (type.isUsingGenerics()) {
                ClassNode actualType = getType(expressions.get(i));
                if (isVargs && lastArg && actualType.isArray()) {
                    actualType=actualType.getComponentType();
                }
                actualType = wrapTypeIfNecessary(actualType);
                Map<String, GenericsType> typePlaceholders = GenericsUtils.extractPlaceholders(type.isArray()?type.getComponentType():type);
                if (OBJECT_TYPE.equals(type)) {
                    // special case for handing Object<E> -> Object
                    for (String key : typePlaceholders.keySet()) {
                        resolvedPlaceholders.put(key, new GenericsType(actualType));
                    }
                } else {
                    while (!actualType.equals(type)) {
                        Set<ClassNode> interfaces = actualType.getAllInterfaces();
                        boolean intf = false;
                        for (ClassNode anInterface : interfaces) {
                            if (anInterface.equals(type)) {
                                intf = true;
                                actualType = GenericsUtils.parameterizeInterfaceGenerics(actualType, anInterface);
                            }
                        }
                        if (!intf) actualType = actualType.getUnresolvedSuperClass();
                    }
                    Map<String, GenericsType> actualTypePlaceholders = GenericsUtils.extractPlaceholders(actualType);
                    for (Map.Entry<String, GenericsType> typeEntry : actualTypePlaceholders.entrySet()) {
                        String key = typeEntry.getKey();
                        GenericsType value = typeEntry.getValue();
                        GenericsType alias = typePlaceholders.get(key);
                        if (alias != null && alias.isPlaceholder()) {
                            resolvedPlaceholders.put(alias.getName(), value);
                        }
                    }
                }

            }
        }
        GenericsType[] copy = new GenericsType[returnTypeGenerics.length];
        for (int i = 0; i < copy.length; i++) {
            GenericsType returnTypeGeneric = returnTypeGenerics[i];
            if (returnTypeGeneric.isPlaceholder() || returnTypeGeneric.isWildcard()) {
                GenericsType resolved = resolvedPlaceholders.get(returnTypeGeneric.getName());
                if (resolved==null) resolved = returnTypeGeneric;
                copy[i] = resolved;
            } else {
                copy[i] = returnTypeGeneric;
            }
        }
        if (returnType.equals(OBJECT_TYPE)) {
            return copy[0].getType();
        }
        returnType = returnType.getPlainNodeReference();
        returnType.setGenericsTypes(copy);
        if (returnType.equals(Annotation_TYPE) && returnType.getGenericsTypes()!=null && !returnType.getGenericsTypes()[0].isPlaceholder()) {
            return returnType.getGenericsTypes()[0].getType();
        }

After Change


            }
        }
        if (!isUsingGenericsOrIsArrayUsingGenerics(returnType)) return returnType;        
        GenericsType[] returnTypeGenerics = returnType.isArray()?returnType.getComponentType().getGenericsTypes():returnType.getGenericsTypes();
        List<GenericsType> placeholders = new LinkedList<GenericsType>();
        for (GenericsType returnTypeGeneric : returnTypeGenerics) {
            if (returnTypeGeneric.isPlaceholder() || returnTypeGeneric.isWildcard()) {
                placeholders.add(returnTypeGeneric);
            }
        }
        if (placeholders.isEmpty()) return returnType; // nothing to infer
        Map<String,GenericsType> resolvedPlaceholders = new HashMap<String, GenericsType>();
        GenericsUtils.extractPlaceholders(receiver, resolvedPlaceholders);
        GenericsUtils.extractPlaceholders(method.getReturnType(), resolvedPlaceholders);
        // then resolve receivers from method arguments
        Parameter[] parameters = method.getParameters();
        boolean isVargs = isVargs(parameters);
        ArgumentListExpression argList = InvocationWriter.makeArgumentList(arguments);
        List<Expression> expressions = argList.getExpressions();
        int paramLength = parameters.length;
        if (expressions.size()>=paramLength) {
            for (int i = 0; i < paramLength; i++) {
                boolean lastArg = i == paramLength - 1;
                ClassNode type = parameters[i].getType();
                if (!type.isUsingGenerics() && type.isArray()) type = type.getComponentType();
                if (type.isUsingGenerics()) {
                    ClassNode actualType = getType(expressions.get(i));
                    if (isVargs && lastArg && actualType.isArray()) {
                        actualType = actualType.getComponentType();
                    }
                    actualType = wrapTypeIfNecessary(actualType);
                    Map<String, GenericsType> typePlaceholders = GenericsUtils.extractPlaceholders(type.isArray() ? type.getComponentType() : type);
                    if (OBJECT_TYPE.equals(type)) {
                        // special case for handing Object<E> -> Object
                        for (String key : typePlaceholders.keySet()) {
                            resolvedPlaceholders.put(key, new GenericsType(actualType));
                        }
                    } else {
                        while (!actualType.equals(type)) {
                            Set<ClassNode> interfaces = actualType.getAllInterfaces();
                            boolean intf = false;
                            for (ClassNode anInterface : interfaces) {
                                if (anInterface.equals(type)) {
                                    intf = true;
                                    actualType = GenericsUtils.parameterizeInterfaceGenerics(actualType, anInterface);
                                }
                            }
                            if (!intf) actualType = actualType.getUnresolvedSuperClass();
                        }
                        Map<String, GenericsType> actualTypePlaceholders = GenericsUtils.extractPlaceholders(actualType);
                        for (Map.Entry<String, GenericsType> typeEntry : actualTypePlaceholders.entrySet()) {
                            String key = typeEntry.getKey();
                            GenericsType value = typeEntry.getValue();
                            GenericsType alias = typePlaceholders.get(key);
                            if (alias != null && alias.isPlaceholder()) {
                                resolvedPlaceholders.put(alias.getName(), value);
                            }
                        }
                    }

                }
            }
        }
        GenericsType[] copy = new GenericsType[returnTypeGenerics.length];
        for (int i = 0; i < copy.length; i++) {
            GenericsType returnTypeGeneric = returnTypeGenerics[i];
            if (returnTypeGeneric.isPlaceholder() || returnTypeGeneric.isWildcard()) {
                GenericsType resolved = resolvedPlaceholders.get(returnTypeGeneric.getName());
                if (resolved==null) resolved = returnTypeGeneric;
                copy[i] = resolved;
            } else {
                copy[i] = returnTypeGeneric;
            }
        }
        if (returnType.equals(OBJECT_TYPE)) {
            return copy[0].getType();
        }
        if (returnType.isArray()) {
            returnType = returnType.getComponentType().getPlainNodeReference();
            returnType.setGenericsTypes(copy);
            if (OBJECT_TYPE.equals(returnType)) {
                // replace Object<Component> with Component
                returnType = copy[0].getType();
            }
            returnType = returnType.makeArray();
        } else {
            returnType = returnType.getPlainNodeReference();
            returnType.setGenericsTypes(copy);
        }
        if (returnType.equals(Annotation_TYPE) && returnType.getGenericsTypes()!=null && !returnType.getGenericsTypes()[0].isPlaceholder()) {
            return returnType.getGenericsTypes()[0].getType();